package sqs

import (
	"os"
	"fmt"
	"http"
	"strconv"
	"goaws.googlecode.com/hg/aws"
)

type Queue struct {
	Conn *Conn
	Path string
}

type Permission struct {
	Label       string
	Permissions []struct {
		AWSAccountId, ActionName string
	}
}

func (q *Queue) String() string {
	return "SQS queue at " + q.Conn.URL + q.Path
}

func (c *Conn) newQueue(rawurl string) *Queue {
	url, _ := http.ParseURL(rawurl)
	return &Queue{c, url.Path}
}

func (c *Conn) CreateQueue(name string, defaultVisibilityTimeout int) (q *Queue, err os.Error) {
	var params = map[string]string{"QueueName": name}
	if defaultVisibilityTimeout >= 0 {
		params["DefaultVisibilityTimeout"] = strconv.Itoa(defaultVisibilityTimeout)
	}

	response := new(createQueueResponse)
	if err = c.getResponse("CreateQueue", "/", params, response); err != nil {
		return
	}

	return c.newQueue(response.URL), nil
}

func (c *Conn) OpenQueue(name string) (q *Queue, err os.Error) {
	return c.CreateQueue(name, -1)
}

func (c *Conn) ListQueues(prefix string) (queues []*Queue, err os.Error) {
	response := new(listQueuesResponse)
	if err = c.getResponse("ListQueues", "/", map[string]string{"QueueNamePrefix": prefix}, response); err != nil {
		return
	}

	queues = make([]*Queue, 0, len(response.URLs))
	for _, url := range response.URLs {
		queues = append(queues, c.newQueue(url))
	}

	return queues, nil
}

func (c *Conn) DeleteQueue(queuePath string) os.Error {
	return c.getResponse("DeleteQueue", queuePath, nil, nil)
}

func (q *Queue) getResponse(action string, params map[string]string, xmlResp interface{}) os.Error {
	return q.Conn.getResponse(action, q.Path, params, xmlResp)
}

func (q *Queue) Delete() os.Error {
	return q.Conn.DeleteQueue(q.Path)
}

func (q *Queue) GetAttributes(names []string) (attrs aws.AttributeList, err os.Error) {
	params := aws.AddAttributeNamesToParams(nil, names)

	response := new(getQueueAttributesResponse)
	if err = q.getResponse("GetQueueAttributes", params, response); err != nil {
		return
	}

	return response.Attributes, nil
}

func (q *Queue) GetAllAttributes() (attrs aws.AttributeList, err os.Error) {
	return q.GetAttributes([]string{"All"})
}

func (q *Queue) SetAttributes(attrs aws.AttributeList) (err os.Error) {
	return q.getResponse("SetQueueAttributes", attrs.AddToParams(nil), nil)
}

func (q *Queue) AddPermission(perm Permission) os.Error {
	params := make(map[string]string)
	params["Label"] = perm.Label
	for i, accountPerm := range perm.Permissions {
		params[fmt.Sprintf("AWSAccountId.%d", i+1)] = accountPerm.AWSAccountId
		params[fmt.Sprintf("ActionName.%d", i+1)] = accountPerm.ActionName
	}

	return q.getResponse("AddPermission", params, nil)
}

func (q *Queue) RemovePermission(label string) os.Error {
	return q.getResponse("RemovePermission", map[string]string{"Label": label}, nil)
}
